(function(ui){
	var baseControl = {
		init:function(ctr,op){
			// 判断组件是否存在
			if (ctr.length > 0) {
				op = this.initOp(op);
				ctr.managerReg(this.type);
				var xctr = new this.xCtr(ctr,op);
				this.initCtr(xctr,op);
			}
		},
		initOp:function(op){
			var tempConfig = this.config;
			if (tempConfig && typeof tempConfig == "function") {
				this.config = tempConfig();
			}
			var config = $.extend(true,{},this.config.op || this.config);
			op && Ccay.DataHelper.applyChangeData(config,op);
			return config;
		},
		initHandler:function(op){
			var handler = op.handler = $.extend(op.handler,{
				initComplete:$.Callbacks(),
				complete:$.Callbacks()
			});
			//判断是否数据绑定控件，注册绑定控件的handler
			if(this.dataCtr)
			{
				(op.ajax || op.request) && (handler.beforeRequest = $.Callbacks());
				$.extend(handler,{
					beforeBindData : $.Callbacks(),
					dataProcess : $.IHandler(),
					afterBindData : $.Callbacks()
				});
			}
		},
		initCtr:function(xctr,op){
			this.initHandler(op);
			op._initing = true;
			this.runFlow('preInit',xctr,op);
			//插件初始化
			this.plugin.fireAll("preInit",xctr, op);
			
			if(this.dataCtr && !op._reIniting)
			{
				op.Storage = Ccay.Storage.create(op.storageOp,this.dataCtr);
				op.Storage.Cache && (op._cache = true);
				if(op.dataset)
				{
					op.Storage.store(op.dataset);
					delete op.dataset;
				}
			}
			op.fnInit && op.fnInit.call(xctr,op);
			this.runFlow('init',xctr,op).runFlow('build',xctr,op);
			//插件初始化
			this.plugin.fireAll("build",xctr, op);
			this.runFlow('bindEvent',xctr,op);
			
			op.handler.initComplete.fire(xctr,op);
			op.fnInitComplete && op.fnInitComplete.call(xctr,op);
			this.runFlow('initComplete',xctr,op);
			this.checkRequest(xctr,op);
		},
		runFlow:function(flow,xctr,op,para1,para2){
			var fn = this.flow[flow];
			fn && fn.call(this,xctr,op,para1,para2);
			return this;
		},
		checkRequest:function(xctr,op){
			if(op.loadOp)
			{
				this.checkLoad(xctr,op);
			}
			else {
				if(this.dataCtr)
				{
					if(op.ajax)
					{
						var self = this;
						op._reIniting || (op._ajax = op.ajax);
						
						op.ajax = $.extend(true,{},op._ajax);
		
						Ccay.UI.ajax.setFnSuccess(op.ajax,function(result){
							op._requesting = true;
				       		self.bindData(xctr,op,result || {});
				       		delete op._requesting;
				       	});
				       	this.runFlow('initAjax',xctr,op,op.ajax);
					}
					else if(op.request)
						this.runFlow('initAjax',xctr,op);
						
					if(op.autoLoad !== false)
					{
						if(op.Storage.len())
						{
							this.bindData(xctr,op);
							return;
						}//ajax或自定义请求时
						else if(op.ajax || op.request)
						{
							this.request(xctr,op);
							return;
						}
						else
						{
							this.bindData(xctr,op);
						}
					}
					
				}
				this.complete(xctr,op);
			}
		},
		request:function(xctr,op){
			if(op.handler.beforeRequest.fire(xctr,op) !== false)
			{	
				if(!op.fnBeforeRequest || op.fnBeforeRequest.call(xctr,op) !== false)
				{	
					op.fnRequest ? op.fnRequest(xctr,op) : Ccay.UI.ajax(op.ajax);
				}
			}
		},
		bindData:function(xctr,op,data){
			var pageVO,dataset;
			if(data != null){
				pageVO = data.pageVO || (op.pagerOp && op.pagerOp.pageInf);
				dataset = data.result || data;
				op.Storage.store(dataset,pageVO);
			}
			else
			{
				dataset = op.Storage.store();
			}
			//op.dataset = dataset;
			this.runFlow('preBindData',xctr,op,dataset,pageVO);
			
			//执行绑定之前委托方法
        	op.handler.beforeBindData.fire(xctr,op,dataset,pageVO);
        	op.fnBeforeBindData && op.fnBeforeBindData.call(xctr,op,dataset,pageVO);
        	
        	//获取当前绑定的数据
        	var bindData = op.handler.dataProcess.length ? op.handler.dataProcess.fireWithResult(dataset,op,xctr) : dataset;
        	this.runFlow('bindData',xctr,op,bindData);
        	
        	//执行绑定之后委托方法
            op.handler.afterBindData.fire(xctr, op);
            op.fnDataBindComplete && op.fnDataBindComplete.call(xctr);
            this.runFlow('bindDataComplete',xctr,op).complete(xctr,op);
		},
		checkLoad:function(xctr,op){
			if(op.loadOp.content)
			{
				op.loadOp.container.html(content);
				this.load(xctr,op);
			}
			else if(op.loadOp.url)
			{
				var fnSucess = function(){
					this.load(xctr,op);
				}
				op.loadOp.container.ccayLoad(op.loadOp.url,fnSucess,op.noscroll,op.error);
			}
		},
		load:function(xctr,op){
			 op.loadOp.success(xctr,op);
			 this.complete(xctr,op);
		},
		complete:function(xctr,op){
			if(op._initing)
			{
				op.handler.complete.fire(xctr,op);
				op.fnComplete && op.fnComplete.call(xctr);
				this.runFlow('complete',xctr,op);
				delete op._initing;
				xctr.dom.data("xctrInited",true);
			}
		}
	};

	var _XControl = ui.XControl = function(type,flow,config,manager,dataCtr){
		if(typeof(type) == "string")
		{
			var ctrObj = buildManager(type,manager);
			config || (config = {});
			Ccay.UI.Config[type] = config;
			var xctr = ui.XControl[type] = $.IObject({
				type:type,
				config:config,
				flow:flow,
				xCtr:ctrObj,
				dataCtr:dataCtr,
				plugin:$.IAdapter()
				},baseControl);
			return xctr;
		}
	}
	// 添加XControl的插件
	_XControl.addPlugin = function(type,name,plugin){
		ui.XControl[type].fn.plugin.add(name,plugin);
	}
	// 获取XControl的插件
	_XControl.getPlugin = function(type){
		return ui.XControl[type].fn.plugin;
	}
	// 扩展XControl的manager基类
	_XControl.extendIManager = function(type,extend){
		$.extend(_XControl.getIManager(type),extend);
	}
	// 获取XControl的manager基类
	_XControl.getIManager = function(type){
		return ui.XControl[type].fn.xCtr.fn;
	}
	// 判断是否已经重新初始化
	_XControl.isInited = function(dom){
		return dom.data("xctrInited");
	}
	
	var baseManager = {
		init:function(dom,op){
			this.dom = dom;
			if(op)
				this._baseInit(op);
			else
		    	this.op = dom.data(this.type + "_op");
		    this.id = dom.id();
		},
		setOp:function(op){
			this.op = op;
			this.dom.data(this.type + "_op",op);
		},
		_baseInit:function(op){
			this.setOp(op);
			this._manager && this.dom.managerReg(this.type);
		},
		setValue:function(value){
			this.dom.val(value);
		},
		getValue:function(){
			var value = this.dom.getValue();
			return value != null ? value + '' : "";
		},
		disabled:function(enable){
			if(enable)
				this.dom.removeAttr('disabled');
	    	else
	    		this.dom.attr('disabled', 'disabled');
		},
		hide:function(visiable){
			visiable ? this.dom.show() : this.dom.hide();
		},
		readonly:function(writeable){
			if(writeable)
				this.dom.removeAttr('readonly');
	    	else
	    		this.dom.attr('readonly', 'readonly');
		},
		valid:function(){
			return this.dom.valid();
		},
		setDefaultValue:function(value){
			this.dom[0].defaultValue = value;
			return this;
		},
		reset:function(){
			this.dom.setValue(this.dom[0].defaultValue);
			return this;
		},
		reInit:function(op){
			if(this.type)
			{
				var xctr = ui.XControl[this.type],ctr,dom;
				if(xctr)
				{
					dom = this.dom;
					op._reIniting = true;
					DomClass.clear(this);
					ctr = new xctr(dom,op);
					op._reIniting = true;
					return dom.manager();
				}
			}
			return this;
		},
		remove:function(){
			this.dom.remove();
			return this;
		},
		reload:function(data){
			if(this.type)
			{
				var xctr = ui.XControl[this.type];
				if(xctr)
				{
					if(data === true)
						xctr.fn.request(this,this.op);
					else
						xctr.fn.bindData(this,this.op,data);
				}
			}
			return this;
		},
		request:function(param){
			if(this.type)
			{
				var xctr = ui.XControl[this.type],op = this.op;
				if(xctr)
				{
					//更新参数
					if(param)
					{
						//合并默认请求条件
						if (op.ajax.params != null)
							param = $.extend(true, {}, op.ajax.params, param);
						op.ajax.data = param;
					}
					xctr.fn.request(this,op);
				}
			}
			return this;
		}
	};
	
	var buildManager = function(type,manager){
		manager || (manager = {});
		manager.type = type;
		var ctr = $.IObject(manager,baseManager);
		Ccay.UI.regManager(type,function(dom){
			return new ctr(dom);
		});
		return ctr;
	};
	
	ui.getCtrHandler = function (ctr, name) {
		return ctr.data(name);
	};
	ui.setCtrHandler = function (ctr, name, value) {
		ctr.data(name, value);
	};
	ui.fireCtrHandler = function (ctr, name, params) {
		var handler = ui.getCtrHandler(ctr, name);
		if(handler)
			handler.call(ctr, params);
	};
})(Ccay.UI);